<!-- 
entry.isIntersecting 和 entry.intersectionRatio > 0 都是在使用 Intersection Observer API 时，用于判断目标元素与其祖先元素或视口（viewport）的交叉状态的属性或条件。

entry.isIntersecting：
这是一个布尔值（Boolean），表示目标元素是否与其祖先元素或视口相交。
当目标元素至少有一部分可见时，entry.isIntersecting 为 true。
当目标元素完全不可见时，entry.isIntersecting 为 false。
entry.intersectionRatio > 0：
entry.intersectionRatio 是一个介于 0 和 1 之间的数字，表示目标元素与其祖先元素或视口的交叉区域占目标元素总区域的比例。
当 entry.intersectionRatio > 0 时，表示目标元素至少有一部分是可见的。
这个比例越接近 1，表示目标元素可见的部分越多；越接近 0，表示目标元素可见的部分越少。


    if (entry.isIntersecting) {
      console.log('元素进入视口或祖先元素区域');
      // 在这里执行元素进入视口时的操作
    } else {
      console.log('元素完全离开视口或祖先元素区域');
      // 在这里执行元素离开视口时的操作
    }
 
    if (entry.intersectionRatio > 0) {
      console.log('元素部分或全部可见，可见比例为:', entry.intersectionRatio);
      // 根据可见比例执行不同的操作
    } 
-->
    
<template >
  <div class="lazy-image" ref="wzbLazyImageBox">
    <div v-show="!loaded" class="loading-box">
      <slot>
        <div class="defalut-loading-main">loading</div>
      </slot>
    </div>
    <img
      v-show="loaded"
      :data-src="props.imgSrc"
      @load="loaded = true"
      @error="loaded = false"
      ref="lazyImageTag"
      alt="Image"
    />
  </div>
</template>
<script setup>
import { ref, onMounted, watch, nextTick } from "vue";

const props = defineProps({
  imgSrc: String,
});

const wzbLazyImageBox = ref();
const lazyImageTag = ref();
const loaded = ref(false);

const lazyLoadImage = (imageBox, image) => {
  const observer = new IntersectionObserver(
    (entries) => {
      const entry = entries[0];
      if (entry.isIntersecting) {
        image.src = image.getAttribute("data-src");
        observer.unobserve(image);
      }
    },
    {
      root: null,
      threshold: 0,
    }
  );
  observer.observe(imageBox);
};

// 监听 imgSrc 变化
watch(
  () => props.imgSrc,
  async (newSrc, oldSrc) => {
    if (!newSrc) return;
    await nextTick();
    if (wzbLazyImageBox.value && lazyImageTag.value) {
      lazyLoadImage(wzbLazyImageBox.value, lazyImageTag.value);
    }
  },
  { immediate: true }
);
</script>
<style lang="scss" scoped>
.lazy-image {
  width: 100%;
  height: 100%;
  overflow: hidden;
  position: relative;
  & > img {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }
  & > .loading-box {
    width: 100%;
    height: 100%;
    .defalut-loading-main {
      width: 100%;
      height: 100%;
      display: flex;
      justify-content: center;
      align-items: center;
      background: skyblue;
    }
  }
}
</style>
